package com.jxc.service;

import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.jxc.config.CustomerTransactionEnum;
import com.jxc.model.JxcBill;
import com.jxc.model.JxcBillCustomer;
import com.jxc.model.JxcBillCustomerExample;
import com.jxc.model.JxcBillCustomerExt;
import com.jxc.model.JxcBillCustomerItem;
import com.jxc.model.JxcBillExample;
import com.jxc.model.JxcBillExample.Criteria;
import com.jxc.model.JxcBillItem;
import com.jxc.model.JxcBillItemExample;
import com.jxc.model.JxcCustomerTransaction;
import com.jxc.model.JxcCustomerTransactionExample;
import com.jxc.model.PageMode;
import com.jxc.model.mapper.JxcBillCustomerExtMapper;
import com.jxc.model.mapper.JxcBillCustomerItemMapper;
import com.jxc.model.mapper.JxcBillItemMapper;
import com.jxc.model.mapper.JxcBillMapper;
import com.jxc.model.mapper.JxcCustomerTransactionMapper;
import com.jxc.utils.DateUtils;

import lombok.extern.slf4j.Slf4j;

@Service
@Slf4j
public class BillServiceImpl {
	
	@Autowired
	private JxcBillMapper billMapper;
	
	@Autowired
	private JxcBillItemMapper billItemMapper;
	
	@Autowired
	private JxcBillCustomerExtMapper billCustomerExtMapper;
	
	@Autowired
	private JxcCustomerTransactionMapper customerTransactionMapper;
	
	@Autowired
	private JxcBillCustomerItemMapper jxcBillCustomerItemMapper;

	/**
	 * 新建订单
	 * @param data
	 */
	public void save(JSONObject data) {
		JxcBill bill = data.toJavaObject(JxcBill.class);
		
		JxcBillExample example = new JxcBillExample();
		example.createCriteria().andBillNoEqualTo(bill.getBillNo());
		List<JxcBill> tmp = billMapper.selectByExample(example);
		if(tmp != null && !CollectionUtils.isEmpty(tmp)) {
			return;
		}
		if(bill.getCustomerId()==null) {
			Map<String,Object> result = saveBillCustomer(JSONObject.toJSONString(bill));
			bill.setCustomerId((Long) result.get("customerId"));
			if(bill.getCustomerId() == null) {
				log.error("=========客户不存在=========");
				return;
			}
		}

		
		log.info(JSONObject.toJSONString(bill));
		List<JxcBillItem> list = processItem(data);
		if(list.isEmpty() || StringUtils.isEmpty(list.get(0).getGoodsName())) {
			return;
		}
		bill.setTotalAmount(BigDecimal.ZERO);
		billMapper.insertSelective(bill);
		list.stream().forEach(item ->{
			item.setBillId(bill.getId());
			billItemMapper.insertSelective(item);
			if(item.getAmount()!=null) {
				bill.setTotalAmount(bill.getTotalAmount().add(item.getAmount()));
			}
		});
		billMapper.updateByPrimaryKeySelective(bill);
	}

	/**
	 * 处理商品详情
	 * @param data
	 * @return
	 */
	private List<JxcBillItem> processItem(JSONObject data) {
		List<JxcBillItem> bis = Lists.newArrayList();
		JSONArray goods = data.getJSONArray("goodsName");
		JSONArray goodsType = data.getJSONArray("goodsType");
		JSONArray remark = data.getJSONArray("remark");
		JSONArray unitPrice = data.getJSONArray("unitPrice");
		JSONArray num = data.getJSONArray("num");
		JSONArray amount = data.getJSONArray("amount");
		if(goods == null) {
			return Lists.newArrayList();
		}
		int count = goods.size();
		for(int i=0;i<count;i++) {
			JxcBillItem item = new JxcBillItem();
			item.setGoodsName(goods.getString(i));
			item.setGoodsType(goodsType.getString(i));
			item.setRemark(remark.getString(i));
			item.setUnitPrice(unitPrice.getBigDecimal(i));
			item.setNum(num.getInteger(i));
			item.setAmount(amount.getBigDecimal(i));
			bis.add(item);
		}
		return bis;
	}
	
	public void saveCustomerItem(JxcBillCustomerExt customerExt) {
		if(customerExt.getItemId() != null) {
			JxcBillCustomerItem item = new JxcBillCustomerItem();
			BeanUtils.copyProperties(customerExt, item);
			item.setId(customerExt.getItemId());
			
			jxcBillCustomerItemMapper.updateByPrimaryKeySelective(item);
		}else {
			JxcBillCustomerItem item = new JxcBillCustomerItem();
			item.setAddress(customerExt.getAddress());
			item.setCustomerId(customerExt.getId());
			item.setMobile(customerExt.getMobile());
			item.setReceiver(customerExt.getReceiver());
			
			jxcBillCustomerItemMapper.insertSelective(item);
		}
	}

	/**
	 * 查询订单
	 * @param json
	 * @return
	 */
	public Map<String,Object> query(String json) {
		JSONObject request = JSONObject.parseObject(json);
		
		JxcBillExample example = new JxcBillExample();
		Criteria param = example.createCriteria();
		if(request.getLong("customerId")!=null) {
			param.andCustomerIdEqualTo(request.getLong("customerId"));
		}
		if(!StringUtils.isEmpty(request.getString("company"))) {
//			param.andReceiverLike(request.getString("receiver")+"%");
//			param.andCompanyEqualTo(request.getString("company"));
			param.andCompanyLike(request.getString("company")+"%");
		}
		if(!StringUtils.isEmpty(request.getString("mobile"))) {
			param.andMobileEqualTo(request.getString("mobile"));
		}
		if(request.getDate("startTime")!=null) {
			param.andCreatedAtGreaterThan(request.getDate("startTime"));
		}
		if(request.getDate("endTime")!=null) {
			param.andCreatedAtLessThan(request.getDate("endTime"));
		}
		List<JxcBill> tmp = billMapper.selectByExample(example);
		Map<String,Object> result = Maps.newHashMap();
		JxcBill tmpBill = new JxcBill();
		tmpBill.setTotalAmount(BigDecimal.ZERO);
		tmp.stream().forEach(item ->{
			tmpBill.setTotalAmount(tmpBill.getTotalAmount().add(item.getTotalAmount()));
		});
		result.put("list", tmp);
		result.put("totalMoney", tmpBill.getTotalAmount());
		return result;
	}

	/**
	 * 查询订单详情
	 * @param json
	 * @return
	 */
	public Map<String,Object> queryBillDetail(String json) {
		JSONObject request = JSONObject.parseObject(json);
		JxcBill bill = billMapper.selectByPrimaryKey(request.getLong("billId"));
		
		JxcBillItemExample example = new JxcBillItemExample();
		example.createCriteria().andBillIdEqualTo(request.getLong("billId"));
		List<JxcBillItem> billItemList = billItemMapper.selectByExample(example);
		
		Map<String,Object> data = Maps.newHashMap();
		data.put("bill", bill);
		data.put("billItemList", billItemList);
		return data;
	}

	/**
	 * 保存客户
	 * @param json
	 * @return
	 */
	public Map<String,Object> saveBillCustomer(String json) {
		Map<String,Object> result = Maps.newHashMap();
		JxcBillCustomerExt customer = JSONObject.parseObject(json, JxcBillCustomerExt.class);
		JxcBillCustomerExample exa = new JxcBillCustomerExample();
		com.jxc.model.JxcBillCustomerExample.Criteria cri = exa.createCriteria();
		cri.andCompanyEqualTo(customer.getCompany());//同一个单位只有一个
//		if(!StringUtils.isEmpty(customer.getMobile())) {
//			cri.andMobileEqualTo(customer.getMobile());
//		}
		List<JxcBillCustomer> recordList = billCustomerExtMapper.selectByExample(exa);
		if(customer.getItemId()!=null) {
			JxcBillCustomerItem item = jxcBillCustomerItemMapper.selectByPrimaryKey(customer.getItemId());
			customer.setId(item.getCustomerId());
			if(CollectionUtils.isEmpty(recordList) || recordList.get(0).getId().equals(customer.getId())) {
				billCustomerExtMapper.updateByPrimaryKeySelective(customer);
			}else {
				result.put("customerId", item.getCustomerId());
			}
		}else {
			if(CollectionUtils.isEmpty(recordList)){
				billCustomerExtMapper.insertSelective(customer);
				result.put("customerId", customer.getId());
			}else {
				customer.setId(recordList.get(0).getId());
				result.put("customerId", customer.getId());
			}
		}
		saveCustomerItem(customer);
		result.put("status", "success");
		result.put("msg", "保存成功");
		return result;
	}

	public Object queryCompanyList(String json) {
		JxcBillCustomerExt customer = JSONObject.parseObject(json, JxcBillCustomerExt.class);
		if(StringUtils.isNotBlank(customer.getCompany())) {
			customer.setCompanyLike(customer.getCompany()+"%");
		}
		return billCustomerExtMapper.getCompanyList(customer);
	}
	
	public Object queryCustomerList(String json) {
		JxcBillCustomerExt customer = JSONObject.parseObject(json, JxcBillCustomerExt.class);
		if(StringUtils.isNotBlank(customer.getCompany())) {
			customer.setCompanyLike(customer.getCompany()+"%");
		}
		Map<String,Object> obj = Maps.newHashMap();
		PageMode pageMode = JSONObject.parseObject(json, PageMode.class);
		List  list = billCustomerExtMapper.getReceiverList(customer,pageMode);
		obj.put("rows", list);
		obj.put("total", billCustomerExtMapper.countReceiverList(customer));
		return obj;
	}

	public Object customerTransaction(String json) {
		JxcCustomerTransaction transaction = JSONObject.parseObject(json, JxcCustomerTransaction.class);
		customerTransactionMapper.insertSelective(transaction);
		return "success";
	}

	public Object queryTransactionList(String json) {
		JSONObject request = JSONObject.parseObject(json);
		return null;
	}

	public Map<String, Object> buildBillStatement(JSONObject parseObject) {
		Map<String,Object> data = Maps.newHashMap();
		Date date = parseObject.getDate("endTime");
		data.put("year", DateUtils.format(date, "yyyy"));
		
		Long customerId = parseObject.getLong("customerId");
		JxcBillCustomer customer = billCustomerExtMapper.selectByPrimaryKey(customerId);
		data.put("company", customer.getCompany());
		
		//订单
		Map<String,Object> result = query(parseObject.toJSONString());
		List<JxcBill> list = (List<JxcBill>) result.get("list");
		data.put("totalAmount", result.get("totalAmount"));
		List<Map<String,Object>> billList = Lists.newArrayList();
		list.stream().forEach(bill ->{
			Map<String,Object> tmp = Maps.newHashMap();
			tmp.put("createdAt", bill.getCreatedAt());
			tmp.put("billNo", bill.getBillNo());
			
			Map<String,Object> billItemMap= queryBillDetail("{'billId':"+bill.getId()+"}");
			tmp.put("billItemList", billItemMap.get("billItemList"));
			billList.add(tmp);
		});
		data.put("billList", billList);
		//开票金额
		JxcCustomerTransactionExample example = new JxcCustomerTransactionExample();
		example.createCriteria().andCustomerIdEqualTo(customerId)
		.andTypeEqualTo(CustomerTransactionEnum.KAIPIAO.getType());
		 List<JxcCustomerTransaction> transactionList = customerTransactionMapper.selectByExample(example);
		 BigDecimal augend = BigDecimal.ZERO;
		 for(JxcCustomerTransaction record : transactionList) {
			 augend = record.getAmount().add(augend); 
		 }
		data.put("spentedInvoice", 0);
		//收款记录
		example.createCriteria().andCustomerIdEqualTo(customerId)
		.andTypeEqualTo(CustomerTransactionEnum.SHOUKUAN.getType());
		transactionList = customerTransactionMapper.selectByExample(example);
		data.put("transactionList", transactionList);
		return data;
	}
}
